# 音频检测
import os
import queue
import numpy as np
import sounddevice as sd
import soundfile as sf
from collections import deque


class MacAudioPlayer:
    def __init__(self):
        """Mac专用初始化"""
        self.sample_rate = 16000
        self.chunk_size = int(self.sample_rate * 0.3)  # 300ms
        self.audio_queue = queue.Queue(maxsize=3)

        # Mac特定音频配置
        sd.default.samplerate = self.sample_rate
        sd.default.channels = 1
        sd.default.dtype = 'float32'
        sd.default.device = None  # 让PortAudio自动选择最佳设备

        # 验证音频系统
        self._verify_mac_audio()

    def _verify_mac_audio(self):
        """Mac音频子系统验证"""
        print("\n[Mac音频验证]")
        try:
            # 测试基础音频输出
            test_wave = np.sin(2 * np.pi * 440 * np.arange(10000) / 10000)
            sd.play(test_wave, blocking=True)
            print("✓ 基础音频测试通过")

            # 检查设备权限
            if not os.popen("sudo -v 2>&1").read().strip():
                print("⚠ 建议授予终端音频权限：")
                print("1. 打开『系统设置』→『隐私与安全性』→『麦克风』")
                print("2. 确保终端/Terminal被勾选")
        except Exception as e:
            print(f"音频初始化失败: {str(e)}")
            self._show_mac_troubleshooting()

    def _show_mac_troubleshooting(self):
        """Mac特定问题解决指南"""
        print("\n🔧 Mac专用故障排除:")
        print("1. 运行以下命令重置音频驱动:")
        print("   sudo killall coreaudiod")
        print("2. 检查Soundflower是否冲突:")
        print("   brew list | grep soundflower")
        print("3. 尝试切换音频设备:")
        print("   python3 -c \"import sounddevice as sd; print(sd.query_devices())\"")

    def play_file(self, file_path):
        """安全播放流程"""
        try:
            # 加载音频文件（强制单声道）
            audio, sr = sf.read(file_path, dtype='float32', always_2d=True)
            audio = np.mean(audio, axis=1)

            if sr != self.sample_rate:
                print(f"重采样 {sr}Hz → {self.sample_rate}Hz")
                audio = self._resample_audio(audio, sr)

            # 启动音频流（Mac推荐使用高优先级）
            with sd.OutputStream(
                    callback=self._audio_callback,
                    blocksize=self.chunk_size,
                    latency='high'
            ) as stream:
                print("\n▶ 开始播放... (按Ctrl+C停止)")
                for i in range(0, len(audio), self.chunk_size):
                    chunk = audio[i:i + self.chunk_size]
                    if len(chunk) < self.chunk_size:
                        chunk = np.pad(chunk, (0, self.chunk_size - len(chunk)))
                    self.audio_queue.put(chunk.reshape(-1, 1))
                    print(f"正在播放: {i / self.sample_rate:.2f}s", end='\r')
        except KeyboardInterrupt:
            print("\n⏹ 播放停止")
        except Exception as e:
            print(f"播放错误: {str(e)}")
            self._show_mac_troubleshooting()

    def _audio_callback(self, outdata, frames, time, status):
        """Mac优化版回调"""
        try:
            data = self.audio_queue.get_nowait()
            outdata[:] = data[:frames] if data.shape[0] >= frames else np.zeros((frames, 1))
        except queue.Empty:
            outdata.fill(0)
        except Exception as e:
            print(f"回调错误: {str(e)}")
            outdata.fill(0)

    def _resample_audio(self, audio, orig_sr):
        """高质量重采样"""
        from scipy.signal import resample_poly
        gcd = np.gcd(orig_sr, self.sample_rate)
        up = self.sample_rate // gcd
        down = orig_sr // gcd
        return resample_poly(audio, up, down)


if __name__ == "__main__":
    player = MacAudioPlayer()
    test_file = "/synthesized_speech_20250401_202411.wav"  # 替换为你的测试文件

    # 生成测试音频（440Hz正弦波）
    if not os.path.exists(test_file):
        test_wave = np.sin(2 * np.pi * 440 * np.arange(16000 * 2) / 16000)  # 2秒音频
        sf.write(test_file, test_wave, 16000)
        print(f"已生成测试音频: {test_file}")

    player.play_file(test_file)